package org.hagen.mmia.yars.agent.utils;

import net.sf.javailp.Linear;
import net.sf.javailp.OptType;
import net.sf.javailp.Problem;
import net.sf.javailp.Result;
import net.sf.javailp.Solver;
import net.sf.javailp.SolverFactory;
import net.sf.javailp.SolverFactoryLpSolve;

public class lpSolver {

	Linear  objective = null;
	Problem problem   = null;
	Result 	result	  = null;
	
	public lpSolver() {
		objective = new Linear();
		problem   = new Problem();
	}
	
	public void addObjective( int user, int doc, double p ) {

		String y = String.format("y%01d%02d", user, doc );
		
		objective.add( p, y );
	}
	
	public void setObjective( ) {
		problem.setObjective(objective, OptType.MAX);
		objective = null;
	}
	
	
	public void setCapacity( int user, int docNum, int c ) {

		Linear capacity = new Linear();
		
		for( int doc=0; doc<docNum; doc++ ) {
			String y = String.format("y%01d%02d", user, doc );
			capacity.add( 1, y );
		}
		
		problem.add(capacity, "<=", c );
	}

	public void setVisits( int userNum, int doc, int n ) {

		Linear visits = new Linear();
		
		for( int user=0; user<userNum; user++ ) {
			String y = String.format("y%01d%02d", user, doc );
			visits.add( 1, y );
		}
		
		problem.add(visits, "<=", n );
	}
	
	public void solve( int userNum, int docNum ) {
		
		for( int doc=0; doc<docNum; doc++ ) {
			
			for( int user=0; user<userNum; user++ ) {

				String y = String.format("y%01d%02d", user, doc );
				problem.setVarType( y, Boolean.class);
			}
		}
		
		SolverFactory factory = new SolverFactoryLpSolve(); // use lp_solve
		factory.setParameter(Solver.VERBOSE, 0);
		factory.setParameter(Solver.TIMEOUT, 100); // set timeout to 100 seconds

		Solver solver = factory.get(); // you should use this solver only once for one problem
		result = solver.solve(problem);
		
		//System.out.println(result);		
	}
	
	public Number get( int user, int doc ) {
	
		String y = String.format("y%01d%02d", user, doc );
		
		return result.getPrimalValue(y);
	}
}
